#pragma once

#include "Const.h"

#include <QString>
#include <QList>

class GameData
{
    friend class AI;
public:
	GameData(int _mr, int _ml);
	virtual ~GameData(void);

	void Init();
	bool Place(int row, int line, GB::CHESS_TYPE type);  
	GB::GAME_RESULT Judge(int row, int line);
    GB::GAME_RESULT Judge(GB::CHESS_TYPE type);
    int Eval(GB::CHESS_TYPE type, int backSteps = 1);
    QList<int> Steps();
    int Row(int index);
    int Line(int index);

private:
	enum BOARD_STATUS
	{
		STATUS_NONE,
		STATUS_BLACK,
		STATUS_WHITE,
		STATUS_INVALID
	};

	int Index(int row, int line);
    BOARD_STATUS Status(int index);
    bool IsFree(int index);
	int GetSeqNum(int row, int line, int dr, int dl);
	int RelIndex(int index, int dr, int dl);
	bool IsFull();
    bool IsEmpty();
    void GetScope(int &left, int &right, int &top, int &bottom);
    bool IsValidRow(int row);
    bool IsValidLine(int line);
    bool HasNearChess(int idx, int area = 2);

    bool PlaceIndex(int index, GB::CHESS_TYPE type);
    void UnPlaceIndex(int index);
    inline int ChessCount() { return chessCount; };

    static const char MyPos = 'A';
    static const char EnemyPos = ' ';
    static const char FreePos = '?';
    static const QString Patterns[];
    static const int PosValue[];
    static const int PatternResults[];
    static const int LIVE4 = 0;
    static const int DIE4A = 1;
    static const int DIE4B = 2;
    static const int DIE4C = 3;
    static const int LIVE3 = 4;
    static const int DIE3A = 5;
    static const int DIE3B = 6;
    static const int DIE3C = 7;
    static const int DIE3D = 8;
    static const int LIVE2 = 9;
    static const int DIE2A = 10;
    static const int DIE2B = 11;
    static const int DIE2C = 12;
    static const int LIVE1 = 13;
    static const int OTHER = 14;
    static const int DWIN = 15;
    int EvalDirects(int row, int line);
    int EvalMulti(GB::CHESS_TYPE type, int backSteps);
    int GetPattern(int row, int line, int dr, int dl, int &myNum);
    int GetPattern(int row, int line, int dr, int dl);
    QString Revert(QString str);

	BOARD_STATUS *data;
	int maxRow;
	int maxLine;
    int maxIndex;
    QList<int> blackSteps;
    QList<int> whiteSteps;
    QList<int> steps;
    int chessCount;
};

